﻿using System;
using System.Collections.Generic;
using System.Text;

using Microsoft.Xna.Framework;

using Daybreak.Core.SceneGraph;

namespace Daybreak.Core.Rendering.Pipeline
{
    public class Sas
    {
        public class World : MatrixAttribute, IObjectLifeTime
        {
            public World() : base(SasSemantic.world) { }
        }

        public class WorldInverse : MatrixAttribute, IObjectLifeTime
        {
            public WorldInverse() : base(SasSemantic.worldinverse) { }

            public void Update(World world)
            {
                Matrix.Invert(ref world.Value, out Value);
            }
        }

        public class WorldInverseTranspose : MatrixAttribute, IObjectLifeTime
        {
            public WorldInverseTranspose() : base(SasSemantic.worldinversetranspose) { }

            public void Update(World world)
            {
                Matrix.Invert(ref world.Value, out Value);

                Matrix.Transpose(ref Value, out Value);

            }
        }

        public class WorldViewProj : MatrixAttribute, IObjectLifeTime
        {
            public WorldViewProj() : base(SasSemantic.worldviewprojection) { }

            public void Update(World world)
            {
                View view = Shared<View>.GetAttribute(SceneObject.Any);
                Projection proj = Shared<Projection>.GetAttribute(SceneObject.Any);

                Value = world.Value * view.Value * proj.Value;
            }
        }

        public class View : MatrixAttribute, IFrameLifeTime
        {
            public View() : base(SasSemantic.view) { }
        }

        public class ViewInverse : MatrixAttribute, IFrameLifeTime
        {
            public ViewInverse() : base(SasSemantic.viewinverse) { }

            public void Update(View view)
            {
                Matrix.Invert(ref view.Value, out Value);
            }
        }

        public class Projection : MatrixAttribute, IFrameLifeTime
        {
            public Projection() : base(SasSemantic.projection) { }
        }

        public class ViewProjection : MatrixAttribute, IFrameLifeTime
        {
            public ViewProjection() : base(SasSemantic.viewprojection) { }

            public void Update(View view, Projection proj)
            {
                Value = view.Value * proj.Value;
            }

        }
        public class CameraPosition : Vector3Attribute, IFrameLifeTime
        {
            public CameraPosition() : base(SasSemantic.cameraposition) { }
        }

        /// <summary>
        /// The color of ambient light
        /// </summary>
        public class AmbientLightColor : ColorAttribute, IFrameLifeTime
        {
            public AmbientLightColor() : base(SasSemantic.ambient) { }
        }

        /// <summary>
        /// The color of light (used both for directional and point light)
        /// </summary>
        public class DiffuseLightColor : ColorAttribute, IFrameLifeTime
        {
            public DiffuseLightColor() : base(SasSemantic.diffuse) { }
        }

        /// <summary>
        /// The specular color of light (used both for directional and point light)
        /// </summary>
        public class SpecularLightColor : ColorAttribute, IFrameLifeTime
        {
            public SpecularLightColor() : base(SasSemantic.specular) { }
        }

        public class LightDirection : Vector3Attribute, IFrameLifeTime
        {
            public LightDirection() : base(SasSemantic.direction) { }
        }

        public class LightPosition : Vector3Attribute, IFrameLifeTime
        {
            public LightPosition() : base(SasSemantic.position) { }
        }

        public class DiffuseTexture2DMap : Texture2DAttribute
        {
            public DiffuseTexture2DMap() : base(SasSemantic.diffuse) { }
        }

        public class DiffuseSkyCubeTexture : TextureCubeAttribute
        {
            public DiffuseSkyCubeTexture() : base(SasSemantic.diffuse) { }
        }

        /// <summary>
        /// The position in world space of current positional entity
        /// </summary>
        public class CurrentNode : ObjectAttribute
        {
            public Vector3 Position;
            public Node Node;

            public CurrentNode() : base(SasSemantic._unknown) { }
        }

    }
}
